CXX=g++
HEADERS=Ex.h Add.h Expr.h functions.h Fx.h Utilities.h Substitution.h ComparerIx.h Mul.h Number.h operators.h Pow.h Sym.h
OBJ=$(HEADERS:.h=.o)
CXXFLAGS=-Wall -pedantic $(FLIB)
LIB=/usr/local/lib/## location of GMP library
INC=/usr/local/include/## location of header files for GMP
NEWLIB=./sympy-cpp-lib/## folder for new built library
PRG=test## name of program that has been used for development and testing

## built static and dynamic library
all: static-lib shared-lib

#installation of the libarary into the standard location /usr/lib and /usr/include
#root's authentication is required
install: all
	cp $(NEWLIB)libsympycpp* $(LIB)
	cp $(NEWLIB)libsympycpp* /usr/lib/
	cp $(NEWLIB)*h $(INC) 
	cp $(NEWLIB)*h /usr/include/

#deinstallation of the libarary into the standard location /usr/lib and /usr/include
#root's authentication is required
deinstall:
	rm -f $(LIB)libsympycpp.*
	rm -f /usr/lib/libsympycpp.*
	rm -f $(INC)sympy-cpp*h
	rm -f /usr/include/sympy-cpp*h	

## static libarary
static-lib: 
	if [ -d $(NEWLIB) ] ; then echo " " ; else echo "no" ; mkdir $(NEWLIB)  ; fi
	make FLIB="-static" libsympycpp.a

## dynamic library	
shared-lib: 
	if [ -d $(NEWLIB) ] ; then echo " " ; else echo "no" ; mkdir $(NEWLIB)  ; fi
	make FLIB="-fPIC" libsympycpp.so

## build static library, generate particular header files	
libsympycpp.a: ${OBJ}
	rm -f $(NEWLIB)*.a
	ar cq $(NEWLIB)$@ $(OBJ)
	cat  Ex.h Expr.h Fx.h functions.h Sym.h | sed '/include ".*.h"/d'> $(NEWLIB)/sympy-cpp.h
	echo "class Ex; class Sym; class Number; class Add; class Mul; class Pow; class Substitution; class ComparerIx; class operators; class Utilities;" > $(NEWLIB)/sympy-cpp-develop.h
	cat  $(HEADERS)  | sed '/include "/d' >> $(NEWLIB)/sympy-cpp-develop.h

## build dynamic library, generate particular header files	
libsympycpp.so:$(OBJ)
	rm -f $(NEWLIB)*.so
	$(CXX) $(CFLAGS) -shared -o $(NEWLIB)$@ $(OBJ)
	cat  Ex.h Expr.h Fx.h functions.h Sym.h | sed '/include ".*.h"/d'> $(NEWLIB)/sympy-cpp.h
	echo "class Ex; class Sym; class Number; class Add; class Mul; class Pow; class Substitution; class ComparerIx; class operators; class Utilities;" > $(NEWLIB)/sympy-cpp-develop.h
	cat  < $(HEADERS) | sed '/include "/d' >> $(NEWLIB)/sympy-cpp-develop.h

## generate dependencies (it should be used when new dependences arise in sympy-cpp sources)
dep:
	$(CXX) -MM *.cpp > dep.list

#delete object files in source folder
clean-src: 
	rm -f *.o $(PRG) *.core *.out

#delete compiled tests
clean-tests:
	rm -f ./tests/*.test

#delete built library
clean-lib:
	rm -f ./sympy-cpp-lib/*

clean: clean-src clean-tests clean-lib

## compile developing program for testing new features
$(PRG): core.o $(OBJ)
	$(CXX) $(CXXFLAGS) core.o $(OBJ) -I $(INC) -L $(LIB) -lgmpxx -lgmp -o $(PRG)

## default compilation rules
%.o : %.cpp 
	$(CXX) $(CXXFLAGS) -I $(INC) -L $(LIB) -lgmpxx -lgmp -c $<

## append dependencies	
-include dep.list
##---------------------------------------------------------
TESTS=tests/Tsubstitute tests/Tpower tests/Tdifferentiation

#static compilation of tests
static-tests: static-lib
	make aux-tests FLIB="-static"

#dynamic compilation of tests	
shared-tests: shared-lib
	make aux-tests FLIB="-fPIC"

#compilation & run
aux-tests: $(TESTS)
	@ echo "\n\n TESTS have been correctly built."
	@ echo "\n\n"
	make run-tests

tests/Tsubstitute: tests/Tsubstitute.cpp tests/tests.h
	$(CXX) $(CXXFLAGS) tests/Tsubstitute.cpp -I ./../$(NEWLIB) -L ./../$(NEWLIB) -o $@.test -lsympycpp -lgmpxx -lgmp

tests/Tpower: tests/Tpower.cpp tests/tests.h
	$(CXX) $(CXXFLAGS) tests/Tpower.cpp -I ./../$(NEWLIB) -L ./../$(NEWLIB) -o $@.test -lsympycpp -lgmpxx -lgmp

tests/Tdifferentiation: tests/Tdifferentiation.cpp tests/tests.h
	$(CXX) $(CXXFLAGS) tests/Tdifferentiation.cpp -I ./../$(NEWLIB) -L ./../$(NEWLIB) -o $@.test -lsympycpp -lgmpxx -lgmp

run-tests:
	@echo "Start: tests of powers ================================================"
	@./tests/Tpower.test
	@echo "End: tests of power ==================================================="
	
	@echo "Start: tests of differentiations ======================================"
	@./tests/Tdifferentiation.test
	@echo "End: tests of differentiations ========================================"
	
	@echo "Start: tests of substitutions ========================================="
	@./tests/Tsubstitute.test
	@echo "End: tests of substitutions ==========================================="
